#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import re
import time
from PyQt5.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QPushButton,
    QLabel, QTextEdit, QFileDialog, QMessageBox, QGroupBox,
    QFormLayout, QCheckBox, QLineEdit, QProgressDialog, QApplication
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QColor
import configparser
import multiprocessing
from concurrent.futures import ThreadPoolExecutor

class ScanThread(QThread):
    # 定义信号
    signal_progress = pyqtSignal(int, str)
    signal_result = pyqtSignal(list, int, int, list)
    signal_error = pyqtSignal(str)
    
    def __init__(self, folder_path, type1_check, type2_check, type3_check, custom_pattern):
        super().__init__()
        self.folder_path = folder_path
        self.type1_check = type1_check
        self.type2_check = type2_check
        self.type3_check = type3_check
        self.custom_pattern = custom_pattern
        self.running = True
    
    def stop(self):
        self.running = False
    
    def run(self):
        try:
            start_time = time.time()
            
            # 第一阶段：快速扫描统计文件数量
            self.signal_progress.emit(0, "正在统计文件数量...")
            total_files = 0
            for _, _, files in os.walk(self.folder_path):
                if not self.running:
                    return
                total_files += len([f for f in files if f.lower().endswith(('.mp4', '.mov', '.avi', '.mkv', '.wmv', '.flv'))])
            
            if total_files == 0:
                self.signal_result.emit([], 0, 0, [])
                return
            
            # 第二阶段：收集文件信息
            self.signal_progress.emit(5, f"正在收集文件信息 (0/{total_files})...")
            
            # 预编译正则表达式以提高性能
            regex_patterns = {
                'type1': re.compile(r'(.*?)(\d+)[-_](\d+)$') if self.type1_check else None,
                'type2': re.compile(r'(.*?)_副本\d*$') if self.type2_check else None,
                'type3': re.compile(r'(.*?)\s*-\s*副本\d*$') if self.type3_check else None,
                'custom': re.compile(self.custom_pattern) if self.custom_pattern else None
            }
            
            # 使用字典存储文件大小、后缀名和时长的组合
            size_type_duration_groups = {}
            video_files = []
            processed_count = 0
            
            # 优化文件遍历方式
            for root, _, files in os.walk(self.folder_path):
                if not self.running:
                    return
                
                # 过滤视频文件
                for file in files:
                    if file.lower().endswith(('.mp4', '.mov', '.avi', '.mkv', '.wmv', '.flv')):
                        if not self.running:
                            return
                        
                        full_path = os.path.join(root, file)
                        try:
                            file_size = os.path.getsize(full_path)
                            # 尝试获取视频时长
                            video_duration = self._get_video_duration(full_path)
                            video_files.append((full_path, file, file_size, video_duration))
                        except Exception as e:
                            continue
                        
                        processed_count += 1
                        if processed_count % 100 == 0:
                            progress = min(50, 5 + (45 * processed_count // total_files))
                            self.signal_progress.emit(progress, f"正在收集文件信息 ({processed_count}/{total_files})...")
            
            # 按照文件大小、后缀名和视频时长初步分组
            for full_path, file, file_size, video_duration in video_files:
                if not self.running:
                    return
                
                _, ext = os.path.splitext(file)
                size_key = file_size  # 始终使用字节级别的精度
                
                if video_duration > 0:
                    key = (size_key, ext.lower(), video_duration)
                else:
                    key = (size_key, ext.lower(), -1)
                
                if key not in size_type_duration_groups:
                    size_type_duration_groups[key] = []
                size_type_duration_groups[key].append((full_path, file))
            
            # 第三阶段：检测重复
            self.signal_progress.emit(50, "正在检测重复文件...")
            
            duplicate_groups = []
            processed_groups = 0
            total_groups = len(size_type_duration_groups)
            
            # 检查是否有勾选任何规则
            has_checked_rule = self.type1_check or self.type2_check or self.type3_check or self.custom_pattern
            
            for key, files_in_group in size_type_duration_groups.items():
                if not self.running:
                    return
                
                processed_groups += 1
                progress = min(95, 50 + (45 * processed_groups // total_groups))
                if processed_groups % 10 == 0:
                    self.signal_progress.emit(progress, f"正在检测重复文件 ({processed_groups}/{total_groups})...")
                
                if len(files_in_group) <= 1:
                    continue
                
                # 新的重复检测逻辑：仅当"Id"相同时判定为同一组重复视频
                id_groups = {}
                for full_path, file in files_in_group:
                    # 从文件名中提取Id
                    video_id = self._extract_video_id(file)
                    if video_id:
                        if video_id not in id_groups:
                            id_groups[video_id] = []
                        id_groups[video_id].append((full_path, file))
                
                # 只有Id相同的文件才视为重复
                for video_id, group_files in id_groups.items():
                    if len(group_files) > 1:
                        duplicate_groups.append(group_files)
                
                # 如果用户勾选了其他规则，也按规则进行匹配
                if has_checked_rule:
                    # 用户勾选了规则，按规则进行匹配
                    rule_temp_groups = {}
                    
                    for full_path, file in files_in_group:
                        compare_key = self._generate_compare_key(file, regex_patterns)
                        if compare_key:
                            rule_type, prefix = compare_key
                            if rule_type not in rule_temp_groups:
                                rule_temp_groups[rule_type] = {}
                            if prefix not in rule_temp_groups[rule_type]:
                                rule_temp_groups[rule_type][prefix] = []
                            rule_temp_groups[rule_type][prefix].append((full_path, file))
                    
                    # 收集重复组
                    for rule_type, temp_groups in rule_temp_groups.items():
                        for prefix, group_files in temp_groups.items():
                            if len(group_files) > 1:
                                # 检查这些文件是否已经有相同的Id
                                id_check_groups = {}
                                for full_path, file in group_files:
                                    video_id = self._extract_video_id(file)
                                    if video_id:
                                        if video_id not in id_check_groups:
                                            id_check_groups[video_id] = []
                                        id_check_groups[video_id].append((full_path, file))
                                
                                # 只有Id相同的文件才添加到重复组
                                for video_id, id_group_files in id_check_groups.items():
                                    if len(id_group_files) > 1:
                                        # 检查是否已经添加过这个组
                                        already_added = False
                                        for existing_group in duplicate_groups:
                                            if set([f[1] for f in id_group_files]).issubset(set([f[1] for f in existing_group])):
                                                already_added = True
                                                break
                                        if not already_added:
                                            duplicate_groups.append(id_group_files)
            
            self.signal_progress.emit(100, "扫描完成")
            total_duplicates = sum(len(group) for group in duplicate_groups)
            self.signal_result.emit(duplicate_groups, len(video_files), total_duplicates, video_files)
            
        except Exception as e:
            self.signal_error.emit(str(e))
    
    def _extract_video_id(self, filename):
        """从文件名中提取视频Id"""
        # 文件名格式示例："商品id588492109410视频标题面包里面居然夹着这么多红豆馅！软乎乎的浓浓的奶香混和香甜的的红豆沙真的太好吃了桃李面包 面包1-3.mp4"
        # 提取"商品id"后的数字
        match = re.search(r'商品id(\d+)', filename)
        if match:
            return match.group(1)
        return None
    
    def _get_video_duration(self, file_path):
        """尝试获取视频文件的时长 - 使用更精确的估算方法"""
        try:
            file_size = os.path.getsize(file_path)
            # 使用更精细的分段估算方法，根据文件大小动态调整估算系数
            if file_size < 10 * 1024 * 1024:  # 小于10MB的文件
                estimated_duration = int(file_size / (2 * 1024 * 1024) * 60)
            elif file_size < 50 * 1024 * 1024:  # 10MB-50MB的文件
                estimated_duration = int(file_size / (4 * 1024 * 1024) * 60)
            elif file_size < 100 * 1024 * 1024:  # 50MB-100MB的文件
                estimated_duration = int(file_size / (6 * 1024 * 1024) * 60)
            else:  # 大于100MB的文件
                estimated_duration = int(file_size / (8 * 1024 * 1024) * 60)
            return estimated_duration
        except:
            return -1
    
    def _generate_compare_key(self, filename, regex_patterns):
        # 移除扩展名
        name_without_ext, ext = os.path.splitext(filename)
        
        # 应用第一种规则
        if self.type1_check and regex_patterns['type1']:
            match = regex_patterns['type1'].search(name_without_ext)
            if match:
                prefix = match.group(1).strip()
                return (1, prefix)
        
        # 应用第二种规则
        if self.type2_check and regex_patterns['type2']:
            match = regex_patterns['type2'].search(name_without_ext)
            if match:
                return (2, match.group(1).strip())
        
        # 应用第三种规则
        if self.type3_check and regex_patterns['type3']:
            match = regex_patterns['type3'].search(name_without_ext)
            if match:
                return (3, match.group(1).strip())
        
        # 应用自定义规则
        if regex_patterns['custom']:
            try:
                match = regex_patterns['custom'].search(name_without_ext)
                if match and len(match.groups()) > 0:
                    return (4, match.group(1).strip())
            except re.error:
                pass
        
        return None

class CleanThread(QThread):
    # 定义信号
    signal_progress = pyqtSignal(int, str)
    signal_result = pyqtSignal(int, int)
    signal_error = pyqtSignal(str)
    signal_update = pyqtSignal(str)
    
    def __init__(self, duplicate_groups):
        super().__init__()
        self.duplicate_groups = duplicate_groups
        self.running = True
    
    def stop(self):
        self.running = False
    
    def run(self):
        try:
            deleted_count = 0
            failed_count = 0
            total_to_delete = sum(len(group)-1 for group in self.duplicate_groups)
            deleted_so_far = 0
            
            # 使用线程池进行批量删除操作，提高效率
            with ThreadPoolExecutor(max_workers=min(10, multiprocessing.cpu_count() * 2)) as executor:
                futures = []
                file_to_group = {}
                
                # 提交所有删除任务
                for group in self.duplicate_groups:
                    for i, (full_path, file) in enumerate(group):
                        if i == 0:  # 保留第一个文件
                            self.signal_update.emit(f'✅ 保留: {file}')
                            continue
                        
                        # 提交删除任务到线程池
                        future = executor.submit(self._delete_file, full_path, file)
                        futures.append(future)
                        file_to_group[future] = (full_path, file)
                
                # 检查任务完成情况并更新进度
                for future in futures:
                    if not self.running:
                        return
                    
                    try:
                        success, result = future.result()
                        if success:
                            deleted_count += 1
                            self.signal_update.emit(f'🗑️ 删除: {result}')
                        else:
                            failed_count += 1
                            self.signal_update.emit(f'❌ 删除失败: {result}')
                    except Exception as e:
                        failed_count += 1
                        full_path, file = file_to_group[future]
                        self.signal_update.emit(f'❌ 删除失败: {file} - 错误: {str(e)}')
                    
                    deleted_so_far += 1
                    if deleted_so_far % 10 == 0 or deleted_so_far == total_to_delete:
                        progress = int(100 * deleted_so_far / total_to_delete)
                        self.signal_progress.emit(progress, f"正在删除文件 ({deleted_so_far}/{total_to_delete})...")
            
            self.signal_progress.emit(100, "清理完成")
            self.signal_result.emit(deleted_count, failed_count)
        except Exception as e:
            self.signal_error.emit(str(e))
    
    def _delete_file(self, full_path, file):
        """删除单个文件并返回结果"""
        try:
            if os.path.exists(full_path):
                os.remove(full_path)
            return (True, file)
        except Exception as e:
            return (False, f"{file} - 错误: {str(e)}")

class DuplicateCleanerDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.config = configparser.ConfigParser()
        self.load_config()
        self.duplicate_groups = []
        self.video_files = []
        self.scan_thread = None
        self.clean_thread = None
        self.progress_dialog = None
        self.init_ui()
        
    def load_config(self):
        # 从配置文件加载设置
        if os.path.exists('config.ini'):
            self.config.read('config.ini', encoding='utf-8')
        
        # 初始化重复检测配置
        if not self.config.has_section('duplicate_detection'):
            self.config.add_section('duplicate_detection')
        
        # 设置默认值
        if not self.config.has_option('duplicate_detection', 'enable_type1'):
            self.config.set('duplicate_detection', 'enable_type1', 'false')  # 默认不勾选第一种情况
        
        if not self.config.has_option('duplicate_detection', 'enable_type2'):
            self.config.set('duplicate_detection', 'enable_type2', 'true')  # 默认勾选第二种情况
        
        if not self.config.has_option('duplicate_detection', 'enable_type3'):
            self.config.set('duplicate_detection', 'enable_type3', 'true')  # 默认勾选第三种情况
        
        if not self.config.has_option('duplicate_detection', 'custom_pattern'):
            self.config.set('duplicate_detection', 'custom_pattern', '')  # 默认无自定义模式
    
    def save_config(self):
        # 保存配置到文件
        self.config.set('duplicate_detection', 'enable_type1', str(self.type1_check.isChecked()))
        self.config.set('duplicate_detection', 'enable_type2', str(self.type2_check.isChecked()))
        self.config.set('duplicate_detection', 'enable_type3', str(self.type3_check.isChecked()))
        self.config.set('duplicate_detection', 'custom_pattern', self.custom_pattern_edit.text())
        
        with open('config.ini', 'w', encoding='utf-8') as configfile:
            self.config.write(configfile)
    
    def init_ui(self):
        self.setWindowTitle('一键清除重复视频')
        self.setGeometry(100, 100, 800, 600)
        
        main_layout = QVBoxLayout()
        
        # 文件夹选择
        folder_layout = QHBoxLayout()
        self.folder_label = QLabel('请选择要扫描的文件夹:')
        self.folder_path_edit = QLineEdit()
        self.folder_path_edit.setStyleSheet('''
            QLineEdit {
                border: 1px solid #dfe4ea;
                border-radius: 4px;
                padding: 6px 10px;
                background-color: white;
            }
            QLineEdit:focus {
                border-color: #54a0ff;
                background-color: #f9f9f9;
            }
        ''')
        
        self.select_folder_btn = QPushButton('浏览...')
        self.select_folder_btn.clicked.connect(self.select_folder)
        self.select_folder_btn.setStyleSheet('''
            QPushButton {
                background-color: #5f27cd;
                color: white;
                border-radius: 6px;
                padding: 6px 12px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                background-color: #341f97;
            }
            QPushButton:pressed {
                background-color: #10ac84;
            }
        ''')
        
        folder_layout.addWidget(self.folder_label)
        folder_layout.addWidget(self.folder_path_edit)
        folder_layout.addWidget(self.select_folder_btn)
        main_layout.addLayout(folder_layout)
        
        # 配置选项
        config_group = QGroupBox('重复检测配置')
        config_group.setStyleSheet('''
            QGroupBox {
                border: 1px solid #dfe4ea;
                border-radius: 6px;
                margin-top: 10px;
                padding: 15px;
                font-weight: bold;
                color: #2d3436;
            }
        ''')
        config_layout = QFormLayout()
        
        # 美化所有复选框
        check_box_style = '''
            QCheckBox {
                color: #2d3436;
                font-family: "Microsoft YaHei", Arial, sans-serif;
                font-size: 14px;
                margin-bottom: 5px;
            }
            QCheckBox::indicator {
                width: 18px;
                height: 18px;
                border-radius: 4px;
                border: 2px solid #dfe4ea;
                background-color: white;
            }
            QCheckBox::indicator:checked {
                background-color: #5f27cd;
                border-color: #5f27cd;
                image: url(:/icons/check.png);
            }
            QCheckBox::indicator:hover {
                border-color: #54a0ff;
            }
        '''
        
        # 第一种情况：序号不同的重复视频
        self.type1_check = QCheckBox('启用序号不同的重复检测（如：视频标题1-1.mp4、视频标题1-2.mp4）')
        self.type1_check.setChecked(self.config.getboolean('duplicate_detection', 'enable_type1'))
        self.type1_check.setStyleSheet(check_box_style)
        config_layout.addRow(self.type1_check)
        
        # 第二种情况：带_副本后缀的重复视频
        self.type2_check = QCheckBox('启用_副本后缀的重复检测（如：视频标题.mp4、视频标题_副本.mp4、视频标题_副本2.mp4）')
        self.type2_check.setChecked(self.config.getboolean('duplicate_detection', 'enable_type2'))
        self.type2_check.setStyleSheet(check_box_style)
        config_layout.addRow(self.type2_check)
        
        # 第三种情况：带- 副本后缀的重复视频
        self.type3_check = QCheckBox('启用- 副本后缀的重复检测（如：视频标题.mp4、视频标题 - 副本.mp4）')
        self.type3_check.setChecked(self.config.getboolean('duplicate_detection', 'enable_type3'))
        self.type3_check.setStyleSheet(check_box_style)
        config_layout.addRow(self.type3_check)
        
        # 自定义模式
        self.custom_pattern_label = QLabel('自定义重复模式（正则表达式）:')
        self.custom_pattern_label.setStyleSheet('color: #2d3436; font-family: "Microsoft YaHei", Arial, sans-serif; font-size: 14px;')
        
        self.custom_pattern_edit = QLineEdit()
        self.custom_pattern_edit.setText(self.config.get('duplicate_detection', 'custom_pattern'))
        self.custom_pattern_edit.setStyleSheet('''
            QLineEdit {
                border: 1px solid #dfe4ea;
                border-radius: 4px;
                padding: 6px 10px;
                background-color: white;
            }
            QLineEdit:focus {
                border-color: #54a0ff;
                background-color: #f9f9f9;
            }
        ''')
        
        self.custom_pattern_hint = QLabel('提示：使用正则表达式定义重复文件的模式，捕获组1将用于判断重复。例如：(.*?)\\d+[-_]\\d+ 表示匹配末尾有数字-数字的文件')
        self.custom_pattern_hint.setStyleSheet('color: gray; font-size: 12px; font-family: "Microsoft YaHei", Arial, sans-serif;')
        
        config_layout.addRow(self.custom_pattern_label, self.custom_pattern_edit)
        config_layout.addRow(self.custom_pattern_hint)
        
        config_group.setLayout(config_layout)
        main_layout.addWidget(config_group)
        
        # 操作按钮
        action_layout = QHBoxLayout()
        # 扫描按钮样式 - 使用更统一的蓝色系
        self.scan_btn = QPushButton('扫描重复视频')
        self.scan_btn.clicked.connect(self.scan_duplicates)
        self.scan_btn.setStyleSheet('''
            QPushButton {
                background-color: #2980b9;
                color: white;
                border-radius: 6px;
                padding: 8px 16px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                background-color: #1f618d;
            }
            QPushButton:pressed {
                background-color: #1a5276;
            }
        ''')
        
        # 清除按钮样式 - 使用更醒目的红色系
        self.clean_btn = QPushButton('一键清除重复')
        self.clean_btn.clicked.connect(self.clean_duplicates)
        self.clean_btn.setEnabled(False)  # 初始状态下禁用
        self.clean_btn.setStyleSheet('''
            QPushButton {
                background-color: #e74c3c;
                color: white;
                border-radius: 6px;
                padding: 8px 16px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover:enabled {
                background-color: #c0392b;
            }
            QPushButton:pressed:enabled {
                background-color: #a93226;
            }
            QPushButton:disabled {
                background-color: #cccccc;
                color: #666666;
            }
        ''')
        
        # 保存配置按钮样式 - 使用更统一的绿色系
        self.save_config_btn = QPushButton('保存配置')
        self.save_config_btn.clicked.connect(self.save_config)
        self.save_config_btn.setStyleSheet('''
            QPushButton {
                background-color: #27ae60;
                color: white;
                border-radius: 6px;
                padding: 8px 16px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                background-color: #219a52;
            }
            QPushButton:pressed {
                background-color: #1e8449;
            }
        ''')
        
        action_layout.addWidget(self.scan_btn)
        action_layout.addWidget(self.clean_btn)
        action_layout.addWidget(self.save_config_btn)
        main_layout.addLayout(action_layout)
        
        # 结果显示
        self.result_text = QTextEdit()
        self.result_text.setReadOnly(True)
        # 美化结果显示区域
        self.result_text.setStyleSheet('''
            QTextEdit {
                background-color: #f8f9fa;
                border: 1px solid #dfe4ea;
                border-radius: 6px;
                padding: 10px;
                font-family: "Microsoft YaHei", Arial, sans-serif;
                font-size: 14px;
                color: #2d3436;
            }
            QTextEdit:focus {
                border-color: #54a0ff;
            }
        ''')
        main_layout.addWidget(self.result_text)
        
        # 应用程序全局样式
        self.setStyleSheet('''
            QWidget {
                font-family: "Microsoft YaHei", Arial, sans-serif;
                background-color: #f5f6fa;
            }
            QLabel {
                color: #2d3436;
            }
        ''')
        
        self.setLayout(main_layout)
    
    def select_folder(self):
        folder = QFileDialog.getExistingDirectory(self, '选择要扫描的文件夹')
        if folder:
            self.folder_path_edit.setText(folder)
    
    def scan_duplicates(self):
        folder_path = self.folder_path_edit.text()
        if not folder_path or not os.path.exists(folder_path):
            QMessageBox.warning(self, '警告', '请先选择有效的文件夹路径')
            return
        
        self.result_text.clear()
        self.result_text.append(f'正在扫描文件夹: {folder_path}')
        
        # 禁用按钮防止重复操作
        self.scan_btn.setEnabled(False)
        self.clean_btn.setEnabled(False)
        
        # 创建进度对话框
        self.progress_dialog = QProgressDialog("正在准备扫描...", "取消", 0, 100, self)
        self.progress_dialog.setWindowTitle("扫描进度")
        # 不设置模态类型，使用默认值
        self.progress_dialog.canceled.connect(self.cancel_scan)
        
        # 创建并启动扫描线程
        self.scan_thread = ScanThread(
            folder_path,
            self.type1_check.isChecked(),
            self.type2_check.isChecked(),
            self.type3_check.isChecked(),
            self.custom_pattern_edit.text()
        )
        self.scan_thread.signal_progress.connect(self.update_progress)
        self.scan_thread.signal_result.connect(self.on_scan_complete)
        self.scan_thread.signal_error.connect(self.on_scan_error)
        self.scan_thread.finished.connect(self.on_scan_thread_finished)
        self.scan_thread.start()
    
    @pyqtSlot(int, str)
    def update_progress(self, value, text):
        if self.progress_dialog:
            self.progress_dialog.setValue(value)
            self.progress_dialog.setLabelText(text)
    
    @pyqtSlot(list, int, int, list)
    def on_scan_complete(self, duplicate_groups, total_files, total_duplicates, video_files):
        self.duplicate_groups = duplicate_groups
        self.video_files = video_files
        
        self.result_text.append(f'找到 {total_files} 个视频文件')
        
        if not duplicate_groups:
            self.result_text.append('未发现重复视频文件')
            self.clean_btn.setEnabled(False)
        else:
            # 计算重复视频总数
            # 使用setTextColor方法确保提示信息正确显示
            current_color = self.result_text.textColor()
            self.result_text.setTextColor(QColor('#e74c3c'))  # 使用红色突出显示
            self.result_text.append(f'发现 {len(duplicate_groups)} 组重复视频文件，共 {total_duplicates} 个重复视频：')
            self.result_text.setTextColor(current_color)  # 恢复原来的颜色
            
            # 限制显示的重复组数量，避免UI阻塞
            max_display_groups = 100  # 最多显示100组
            display_groups = duplicate_groups[:max_display_groups]
            
            # 批量更新UI，避免频繁刷新
            batch_text = []
            for i, group in enumerate(display_groups, 1):
                batch_text.append(f'\n组 {i}:')
                # 限制每组显示的文件数量
                max_files_per_group = 10
                displayed_files = group[:max_files_per_group]
                for full_path, file in displayed_files:
                    batch_text.append(f'  - {file}')
                if len(group) > max_files_per_group:
                    batch_text.append(f'  ... 还有 {len(group) - max_files_per_group} 个文件')
                # 显示每组中可以清理的文件数量（带颜色区分）
                batch_text.append(f'  💡 该组可清理 {len(group) - 1} 个文件')
            
            # 一次性添加所有文本
            if batch_text:
                self.result_text.append('\n'.join(batch_text))
            
            # 如果有更多组未显示，添加提示信息
            if len(duplicate_groups) > max_display_groups:
                self.result_text.append(f'\n⚠️  为提高性能，仅显示前 {max_display_groups} 组，实际共有 {len(duplicate_groups)} 组重复文件')
            
            # 在末尾再次打印红色日志
            self.result_text.setTextColor(QColor('#e74c3c'))
            self.result_text.append(f'\n发现 {len(duplicate_groups)} 组重复视频文件，共 {total_duplicates} 个重复视频：')
            self.result_text.setTextColor(current_color)
            
            self.result_text.append('\n💡 提示：重复视频检测基于三个必备条件（文件大小相同、后缀名相同、视频时长相同）以及您勾选的任一重复模式')
            self.clean_btn.setEnabled(True)
        
        # 关闭进度对话框
        if self.progress_dialog:
            self.progress_dialog.close()
            self.progress_dialog = None
    
    @pyqtSlot(str)
    def on_scan_error(self, error_msg):
        QMessageBox.critical(self, '扫描错误', f'扫描过程中发生错误：{error_msg}')
        # 关闭进度对话框
        if self.progress_dialog:
            self.progress_dialog.close()
            self.progress_dialog = None
    
    def on_scan_thread_finished(self):
        # 恢复按钮状态
        self.scan_btn.setEnabled(True)
        # 清理线程引用
        self.scan_thread = None
    
    def cancel_scan(self):
        if self.scan_thread:
            self.scan_thread.stop()
            self.result_text.append('\n扫描已取消')
    
    def clean_duplicates(self):
        if not self.duplicate_groups:
            QMessageBox.information(self, '提示', '没有发现重复文件')
            return
        
        total_to_delete = sum(len(group)-1 for group in self.duplicate_groups)
        
        reply = QMessageBox.question(
            self, '确认操作', 
            f'将清除 {total_to_delete} 个重复文件，是否继续？',
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if reply != QMessageBox.Yes:
            return
        
        # 禁用按钮防止重复操作
        self.scan_btn.setEnabled(False)
        self.clean_btn.setEnabled(False)
        
        # 创建进度对话框
        self.progress_dialog = QProgressDialog("正在准备清理...", "取消", 0, 100, self)
        self.progress_dialog.setWindowTitle("清理进度")
        # 不设置模态类型，使用默认值
        self.progress_dialog.canceled.connect(self.cancel_clean)
        
        # 创建并启动清理线程
        self.clean_thread = CleanThread(self.duplicate_groups)
        self.clean_thread.signal_progress.connect(self.update_progress)
        self.clean_thread.signal_result.connect(self.on_clean_complete)
        self.clean_thread.signal_error.connect(self.on_clean_error)
        self.clean_thread.signal_update.connect(self.update_clean_result)
        self.clean_thread.finished.connect(self.on_clean_thread_finished)
        self.clean_thread.start()
    
    @pyqtSlot(str)
    def update_clean_result(self, text):
        # 限制日志显示行数，避免内存占用过高
        max_lines = 1000
        doc = self.result_text.document()
        if doc:
            current_lines = doc.blockCount()
            if current_lines > max_lines:
                # 获取当前文本
                current_text = self.result_text.toPlainText()
                # 分割成行
                lines = current_text.split('\n')
                # 保留最后的max_lines行
                new_lines = lines[-max_lines:]
                # 重新设置文本
                self.result_text.setPlainText('\n'.join(new_lines))
        
        self.result_text.append(text)
    
    @pyqtSlot(int, int)
    def on_clean_complete(self, deleted_count, failed_count):
        self.result_text.append('\n=== 清理完成 ===')
        self.result_text.append(f'成功删除: {deleted_count} 个文件')
        if failed_count > 0:
            self.result_text.append(f'删除失败: {failed_count} 个文件')
        
        self.clean_btn.setEnabled(False)
        self.duplicate_groups = []
        
        # 关闭进度对话框
        if self.progress_dialog:
            self.progress_dialog.close()
            self.progress_dialog = None
        
        QMessageBox.information(self, '提示', f'✅ 重复文件清理完成\n成功删除: {deleted_count} 个文件\n删除失败: {failed_count} 个文件')
    
    @pyqtSlot(str)
    def on_clean_error(self, error_msg):
        QMessageBox.critical(self, '清理错误', f'清理过程中发生错误：{error_msg}')
        # 关闭进度对话框
        if self.progress_dialog:
            self.progress_dialog.close()
            self.progress_dialog = None
    
    def on_clean_thread_finished(self):
        # 恢复按钮状态
        self.scan_btn.setEnabled(True)
        # 清理线程引用
        self.clean_thread = None
    
    def cancel_clean(self):
        if self.clean_thread:
            self.clean_thread.stop()
            self.result_text.append('\n清理已取消')

if __name__ == '__main__':
    # 仅用于测试
    app = QApplication(sys.argv)
    dialog = DuplicateCleanerDialog()
    dialog.show()
    sys.exit(app.exec_())
